package com.jerry.chinesechess.model;

import com.jerry.chinesechess.enums.PieceType;
import com.jerry.chinesechess.enums.Player;
import com.jerry.chinesechess.util.Constants;
import com.jerry.chinesechess.util.MoveValidator;
import lombok.Data;

@Data
public class Board {
    private Piece[][] grid;
    private Player currentPlayer;
    private boolean isGameOver;
    private Position redGeneralPosition;
    private Position blackGeneralPosition;
    
    public Board() {
        grid = new Piece[Constants.BOARD_HEIGHT][Constants.BOARD_WIDTH];
        currentPlayer = Player.RED;
        initializeBoard();
    }
    
    private void initializeBoard() {
        redGeneralPosition = new Position(9, 4);
        blackGeneralPosition = new Position(0, 4);
        // 初始化红方(下方)
        grid[9][4] = new Piece(PieceType.GENERAL, Player.RED, new Position(9, 4));
        grid[9][3] = new Piece(PieceType.ADVISOR, Player.RED, new Position(9, 3));
        grid[9][5] = new Piece(PieceType.ADVISOR, Player.RED, new Position(9, 5));
        grid[9][2] = new Piece(PieceType.ELEPHANT, Player.RED, new Position(9, 2));
        grid[9][6] = new Piece(PieceType.ELEPHANT, Player.RED, new Position(9, 6));
        grid[9][1] = new Piece(PieceType.HORSE, Player.RED, new Position(9, 1));
        grid[9][7] = new Piece(PieceType.HORSE, Player.RED, new Position(9, 7));
        grid[9][0] = new Piece(PieceType.CHARIOT, Player.RED, new Position(9, 0));
        grid[9][8] = new Piece(PieceType.CHARIOT, Player.RED, new Position(9, 8));
        grid[7][1] = new Piece(PieceType.CANNON, Player.RED, new Position(7, 1));
        grid[7][7] = new Piece(PieceType.CANNON, Player.RED, new Position(7, 7));
        grid[6][8] = new Piece(PieceType.SOLDIER, Player.RED, new Position(6, 8));
        grid[6][6] = new Piece(PieceType.SOLDIER, Player.RED, new Position(6, 6));
        grid[6][4] = new Piece(PieceType.SOLDIER, Player.RED, new Position(6, 4));
        grid[6][2] = new Piece(PieceType.SOLDIER, Player.RED, new Position(6, 2));
        grid[6][0] = new Piece(PieceType.SOLDIER, Player.RED, new Position(6, 0));
        
        // 初始化黑方(上方)
        grid[0][4] = new Piece(PieceType.GENERAL, Player.BLACK, new Position(0, 4));
        grid[0][3] = new Piece(PieceType.ADVISOR, Player.BLACK, new Position(0, 3));
        grid[0][5] = new Piece(PieceType.ADVISOR, Player.BLACK, new Position(0, 5));
        grid[0][2] = new Piece(PieceType.ELEPHANT, Player.BLACK, new Position(0, 2));
        grid[0][6] = new Piece(PieceType.ELEPHANT, Player.BLACK, new Position(0, 6));
        grid[0][1] = new Piece(PieceType.HORSE, Player.BLACK, new Position(0, 1));
        grid[0][7] = new Piece(PieceType.HORSE, Player.BLACK, new Position(0, 7));
        grid[0][0] = new Piece(PieceType.CHARIOT, Player.BLACK, new Position(0, 0));
        grid[0][8] = new Piece(PieceType.CHARIOT, Player.BLACK, new Position(0, 8));
        grid[2][1] = new Piece(PieceType.CANNON, Player.BLACK, new Position(2, 1));
        grid[2][7] = new Piece(PieceType.CANNON, Player.BLACK, new Position(2, 7));
        grid[3][8] = new Piece(PieceType.SOLDIER, Player.BLACK, new Position(3, 8));
        grid[3][6] = new Piece(PieceType.SOLDIER, Player.BLACK, new Position(3, 6));
        grid[3][4] = new Piece(PieceType.SOLDIER, Player.BLACK, new Position(3, 4));
        grid[3][2] = new Piece(PieceType.SOLDIER, Player.BLACK, new Position(3, 2));
        grid[3][0] = new Piece(PieceType.SOLDIER, Player.BLACK, new Position(3, 0));

    }
    
    public boolean movePiece(Position from, Position to) {
        Piece fromPiece = grid[from.getRow()][from.getCol()];
        Piece toPiece = grid[to.getRow()][to.getCol()];
        if (fromPiece == null || fromPiece.getPlayer() != currentPlayer) {
            return false;
        }
        if (!MoveValidator.isValidMove(this, from, to)) {
            return false;
        }

        grid[to.getRow()][to.getCol()] = fromPiece;
        grid[from.getRow()][from.getCol()] = null;
        fromPiece.moveTo(to);
        //可以移动，切换玩家
        if (isPositionSafe()) {
            switchPlayer();
            return true;
        }
        //不可移动，恢复原状
        grid[from.getRow()][from.getCol()] = fromPiece;
        grid[to.getRow()][to.getCol()] = toPiece;
        fromPiece.moveTo(from);
        return false;

    }
    public boolean canMovePiece(Position from, Position to) {
        Piece fromPiece = grid[from.getRow()][from.getCol()];
        Piece toPiece = grid[to.getRow()][to.getCol()];
        if (fromPiece == null || fromPiece.getPlayer() != currentPlayer) {
            return false;
        }
        if (!MoveValidator.isValidMove(this, from, to)) {
            return false;
        }

        grid[to.getRow()][to.getCol()] = fromPiece;
        grid[from.getRow()][from.getCol()] = null;
        fromPiece.moveTo(to);
        Boolean canMove = false;
        //可以移动，恢复原状
        if (isPositionSafe()) {
            canMove = true;
        }
        grid[from.getRow()][from.getCol()] = fromPiece;
        grid[to.getRow()][to.getCol()] = toPiece;
        fromPiece.moveTo(from);
        return canMove;

    }
    
    private void switchPlayer() {
        currentPlayer = currentPlayer == Player.RED ? Player.BLACK : Player.RED;
    }

    public void checkmate() {
        if (isPositionSafe()) {

            return;
        }
        if (isCheckmate()){
            isGameOver = true;
            System.out.println("游戏结束");
        }
    }


    public Piece getPieceAt(Position position) {
        return grid[position.getRow()][position.getCol()];
    }

    /**
     * 是否被将军
     * @return
     */
    public boolean isPositionSafe() {
        Position position = Player.RED == currentPlayer? redGeneralPosition : blackGeneralPosition;
        // 检查任何对手是否可以攻击给定的位置
        for (int row = 0; row < Constants.BOARD_HEIGHT; row++) {
            for (int col = 0; col < Constants.BOARD_WIDTH; col++) {
                Piece piece = grid[row][col];
                if (piece != null && piece.getPlayer() != currentPlayer) {
                    if (MoveValidator.isValidMove(this, new Position(row, col), position)) {
                        return false;
                    }
                }
            }
        }
        return true; // The position is safe
    }

    public boolean isCheckmate() {
        for (int row = 0; row < Constants.BOARD_HEIGHT; row++) {
            for (int col = 0; col < Constants.BOARD_WIDTH; col++) {
                Piece piece = grid[row][col];
                if (piece != null && piece.getPlayer() == currentPlayer) {
                    for (int targetRow = 0; targetRow < Constants.BOARD_HEIGHT; targetRow++) {
                        for (int targetCol = 0; targetCol < Constants.BOARD_WIDTH; targetCol++) {
                            Position from = new Position(row, col);
                            Position to = new Position(targetRow, targetCol);
                            if (canMovePiece(from, to) ) {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }
}